# -*- coding: utf-8 -*-
# @Author  : 袁天琪
import hashlib, time, random, decimal, json, datetime, requests
from application import app, db
from common.models.food.Food import Food
from common.models.food.FoodSaleChangeLog import FoodSaleChangeLog
from common.models.pay.PayOrder import PayOrder
from common.models.pay.PayOrderItem import PayOrderItem
from common.libs.user.Helper import getCurrentDate
from common.libs.food.FoodService import FoodService
from sqlalchemy import func


class PayService():
    def __init__(self):
        pass

    def createOrder(self, member_id, items=None, params=None):
        resp = {'code': 200, 'msg': '操作成功', 'data': {}}
        pay_price = decimal.Decimal(0.00)
        continue_cnt = 0
        food_ids = []
        for item in items:
            if decimal.Decimal(item['price']) < 0:
                continue_cnt += 1
                continue

            pay_price = pay_price + decimal.Decimal(item['price']) * int(item['number'])
            food_ids.append(item['id'])

        if continue_cnt >= len(items):
            resp['code'] = -1
            resp['msg'] = '商品items为空'
            return resp

        yun_price = params['yun_price'] if params and 'yun_price' in params else 0
        note = params['note'] if params and 'note' in params else ''
        express_address_id = params['express_address_id'] if params and 'express_address_id' in params else 0
        express_info = params['express_info'] if params and 'express_info' in params else {}
        yun_price = decimal.Decimal(yun_price)
        total_price = pay_price + yun_price
        try:
            tmp_food_list = db.session.query(Food).filter(Food.id.in_(food_ids)).with_for_update().all()
            tmp_food_stock_mapping = {}
            for tmp_item in tmp_food_list:
                tmp_food_stock_mapping[tmp_item.id] = tmp_item.stock

            model_pay_order = PayOrder()
            model_pay_order.order_sn = self.geneOrderSn()
            model_pay_order.member_id = member_id
            model_pay_order.total_price = total_price
            model_pay_order.yun_price = yun_price
            model_pay_order.pay_price = pay_price
            model_pay_order.note = note
            model_pay_order.status = -8
            model_pay_order.express_status = -8
            model_pay_order.express_address_id = express_address_id
            model_pay_order.express_info = json.dumps(express_info)
            time = getCurrentDate()
            model_pay_order.updated_time = model_pay_order.created_time = time
            model_pay_order.deadline = time + datetime.timedelta(minutes=30)
            db.session.add(model_pay_order)
            #             #db.session.flush()
            for item in items:
                tmp_left_stock = tmp_food_stock_mapping[item['id']]

                if decimal.Decimal(item['price']) < 0:
                    continue

                if int(item['number']) > int(tmp_left_stock):
                    raise Exception("您购买的这美食太火爆了，剩余：%s,你购买%s" % (tmp_left_stock, item['number']))

                tmp_ret = Food.query.filter_by(id=item['id']).update({
                    "stock": int(tmp_left_stock) - int(item['number'])
                })
                if not tmp_ret:
                    raise Exception("下单失败请重新下单")

                tmp_pay_item = PayOrderItem()
                tmp_pay_item.pay_order_id = model_pay_order.id
                tmp_pay_item.member_id = member_id
                tmp_pay_item.quantity = item['number']
                tmp_pay_item.price = item['price']
                tmp_pay_item.food_id = item['id']
                tmp_pay_item.note = note
                time = getCurrentDate()
                tmp_pay_item.updated_time = tmp_pay_item.created_time = time
                tmp_pay_item.deadline = time + datetime.timedelta(minutes=30)
                db.session.add(tmp_pay_item)
                # db.session.flush()

                FoodService.setStockChangeLog(item['id'], -item['number'], "在线购买")
            db.session.commit()
            resp['data'] = {
                'id': model_pay_order.id,
                'order_sn': model_pay_order.order_sn,
                'total_price': str(total_price)
            }
        except Exception as e:
            db.session.rollback()
            print(e)
            resp['code'] = -1
            resp['msg'] = "下单失败请重新下单"
            resp['msg'] = str(e)
            return resp
        return resp

    def closeOrder(self, pay_order_id=0):
        if pay_order_id < 1:
            return False
        pay_order_info = PayOrder.query.filter_by(id=pay_order_id, status=-8).first()
        if not pay_order_info:
            return False

        pay_order_items = PayOrderItem.query.filter_by(pay_order_id=pay_order_id).all()
        if pay_order_items:
            # 需要归还库存
            for item in pay_order_items:
                tmp_food_info = Food.query.filter_by(id=item.food_id).first()
                if tmp_food_info:
                    tmp_food_info.stock = tmp_food_info.stock + item.quantity
                    tmp_food_info.updated_time = getCurrentDate()
                    db.session.add(tmp_food_info)
                    db.session.commit()
                    FoodService.setStockChangeLog(item.food_id, item.quantity, "订单取消")

        pay_order_info.status = 0
        pay_order_info.updated_time = getCurrentDate()
        db.session.add(pay_order_info)
        db.session.commit()
        return True

    def orderSuccess(self, pay_order_id=0):
        try:
            pay_order_info = PayOrder.query.filter_by(id=pay_order_id).first()
            if not pay_order_info or pay_order_info.status not in [-8, -7]:
                return True
            pay_order_info.status = 1
            pay_order_info.express_status = -7
            pay_order_info.updated_time = getCurrentDate()
            pay_order_info.pay_time = getCurrentDate()
            pay_order_info.express_deadline = getCurrentDate() + datetime.timedelta(minutes=10)
            db.session.add(pay_order_info)

            # 售卖历史
            pay_order_items = PayOrderItem.query.filter_by(pay_order_id=pay_order_id).all()
            for order_item in pay_order_items:
                tmp_model_sale_log = FoodSaleChangeLog()
                tmp_model_sale_log.food_id = order_item.food_id
                tmp_model_sale_log.quantity = order_item.quantity
                tmp_model_sale_log.price = order_item.price
                tmp_model_sale_log.member_id = order_item.member_id
                tmp_model_sale_log.created_time = getCurrentDate()
                db.session.add(tmp_model_sale_log)
            # 更新销售数据
            notice_content = []
            if pay_order_items:
                for item in pay_order_items:
                    date_from = datetime.datetime.now().strftime("%Y-%m-01 00:00:00")
                    date_to = datetime.datetime.now().strftime("%Y-%m-31 23:59:59")
                    for item in pay_order_items:
                        tmp_food_info = Food.query.filter_by(id=item.food_id).first()
                        if not tmp_food_info:
                            continue

                        notice_content.append("%s %s份" % (tmp_food_info.name, item.quantity))
                        # 当月数量
                        tmp_stat_info = db.session.query(FoodSaleChangeLog,
                                                         func.sum(FoodSaleChangeLog.quantity).label("total")).filter(
                            FoodSaleChangeLog.food_id == item.food_id).filter(
                            FoodSaleChangeLog.created_time >= date_from,
                            FoodSaleChangeLog.created_time <= date_to).first()
                        tmp_month_count = tmp_stat_info[1] if tmp_stat_info[1] else 0
                        tmp_food_info.total_count += 1
                        tmp_food_info.month_count = tmp_month_count
                        db.session.add(tmp_food_info)

            db.session.commit()
        except Exception as e:
            db.session.rollback()
            print(e)
            return False
        return True

    def geneOrderSn(self):
        m = hashlib.md5()
        sn = None
        while True:
            str = "%s-%s" % (int(round(time.time() * 1000)), random.randint(0, 9999999))
            m.update(str.encode("utf-8"))
            sn = m.hexdigest()
            if not PayOrder.query.filter_by(order_sn=sn).first():
                break
        return sn
